lucky

lucky

跟着好奇心,去探索我觉得酷的东西 希望以电子报分享所见所思的方式,结识更多朋友,碰撞出更多思维火花
github
bilibili
twitter
medium
youtube
zhihu
mastodon
follow
substack

コンピュータネットワーク - トランスポート層

コンピュータネットワーク - トランスポート層#

ネットワーク層はパケットを宛先ホストに送信するだけですが、実際に通信を行うのはホスト内のプロセスです。トランスポート層はプロセス間の論理通信を提供し、トランスポート層は上位のユーザーに対して下位のネットワーク層の核心的な詳細を隠蔽し、アプリケーションが二つのトランスポート層エンティティ間にエンドツーエンドの論理通信チャネルがあるように見せます。

UDP と TCP の特徴#

  • ユーザーデータグラムプロトコル UDP(User Datagram Protocol)はコネクションレスで、最大限の配信を行い、混雑制御がなく、メッセージ指向です(アプリケーションから受け取ったメッセージは統合も分割もせず、ただ UDP ヘッダを追加するだけです)、一対一、一対多、多対一、多対多のインタラクティブ通信をサポートします。

  • トランスポート制御プロトコル TCP(Transmission Control Protocol)はコネクション指向で、信頼性のある配信を提供し、フロー制御、混雑制御を行い、全二重通信を提供し、バイトストリーム指向です(アプリケーション層から受け取ったメッセージをバイトストリームと見なし、バイトストリームをサイズの異なるデータブロックに組織します)、各 TCP 接続はポイントツーポイント(一対一)のみです。

UDP ヘッダ形式#

image

ヘッダフィールドは 8 バイトのみで、ソースポート、デスティネーションポート、長さ、チェックサムを含みます。12 バイトの擬似ヘッダはチェックサムを計算するために一時的に追加されます。

TCP ヘッダ形式#

image

  • シーケンス番号 :バイトストリームに番号を付けるために使用されます。例えばシーケンス番号が 301 の場合、最初のバイトの番号は 301 であり、データ長が 100 バイトの場合、次のメッセージセグメントのシーケンス番号は 401 であるべきです。

  • 確認番号 :期待される次のメッセージセグメントのシーケンス番号です。例えば B が A から送信されたメッセージセグメントを正しく受け取った場合、シーケンス番号は 501 で、データ長は 200 バイトであるため、B は次のメッセージセグメントのシーケンス番号を 701 と期待し、B が A に送信する確認メッセージセグメントの確認番号は 701 になります。

  • データオフセット :データ部分がメッセージセグメントの開始位置からのオフセットを指し、実際にはヘッダの長さを指します。

  • 確認 ACK :ACK=1 の場合、確認番号フィールドは有効であり、そうでない場合は無効です。TCP では、接続が確立された後、すべての送信されるメッセージセグメントは ACK を 1 に設定する必要があります。

  • 同期 SYN :接続確立時にシーケンス番号を同期させるために使用されます。SYN=1、ACK=0 の場合、これは接続要求メッセージセグメントを示します。相手が接続を確立することに同意した場合、応答メッセージには SYN=1、ACK=1 が含まれます。

  • 終了 FIN :接続を解放するために使用されます。FIN=1 の場合、このメッセージセグメントの送信者のデータはすべて送信されており、接続の解放を要求します。

  • ウィンドウ :ウィンドウ値は受信者が送信者に送信ウィンドウを設定させるための基準となります。この制限が必要な理由は、受信者のデータキャッシュスペースが限られているためです。

TCP の三回のハンドシェイク#

image

A をクライアント、B をサーバーと仮定します。

  • まず B は LISTEN(リッスン)状態にあり、クライアントの接続要求を待っています。

  • A は B に接続要求メッセージを送信し、SYN=1、ACK=0、初期シーケンス番号 x を選択します。

  • B は接続要求メッセージを受け取り、接続を確立することに同意した場合、A に接続確認メッセージを送信します。SYN=1、ACK=1、確認番号は x+1 で、初期シーケンス番号 y を選択します。

  • A は B の接続確認メッセージを受け取った後、B に確認を送信し、確認番号は y+1、シーケンス番号は x+1 です。

  • B は A の確認を受け取った後、接続が確立されます。

三回のハンドシェイクの理由

三回目のハンドシェイクは、無効な接続要求がサーバーに到達するのを防ぎ、サーバーが誤って接続を開くのを防ぐためです。

クライアントが送信した接続要求がネットワーク内に滞留している場合、サーバーからの接続確認を受け取るまでに長い時間がかかります。クライアントはタイムアウト再送信時間を待った後、再度接続を要求します。しかし、この滞留した接続要求は最終的にサーバーに到達します。三回のハンドシェイクを行わなければ、サーバーは二つの接続を開くことになります。三回のハンドシェイクがあれば、クライアントはサーバーが送信した滞留接続要求に対する接続確認を無視し、三回目のハンドシェイクを行わないため、再度接続を開くことはありません。

TCP の四回のフィニッシュ#

image

以下の説明ではシーケンス番号と確認番号については議論しません。なぜなら、シーケンス番号と確認番号のルールは比較的単純だからです。また、ACK についても議論しません。なぜなら、接続が確立された後はすべての ACK が 1 だからです。

  • A は接続解放メッセージを送信し、FIN=1 に設定します。

  • B は受信後に確認を送信します。この時点で TCP は半閉状態にあり、B は A にデータを送信できますが、A は B にデータを送信できません。

  • B が接続をもはや必要としない場合、接続解放メッセージを送信し、FIN=1 に設定します。

  • A は受信後に確認を送信し、TIME-WAIT 状態に入り、2 MSL(最大メッセージ生存時間)後に接続を解放します。

  • B は A の確認を受け取った後、接続を解放します。

四回のフィニッシュの理由

クライアントが FIN 接続解放メッセージを送信した後、サーバーがこのメッセージを受け取ると、CLOSE-WAIT 状態に入ります。この状態は、サーバーがまだ送信されていないデータを送信できるようにするためのものです。送信が完了した後、サーバーは FIN 接続解放メッセージを送信します。

TIME_WAIT

クライアントがサーバーからの FIN メッセージを受け取った後、この状態に入ります。この時点で直接 CLOSED 状態に入るのではなく、タイマーが設定した時間 2MSL を待つ必要があります。これには二つの理由があります。

  • 最後の確認メッセージが到達することを保証するためです。もし B が A から送信された確認メッセージを受け取らなかった場合、接続解放要求メッセージを再送信します。A が一定の時間を待つのは、このような状況に対処するためです。

  • 一定の時間を待つのは、この接続の持続時間内に生成されたすべてのメッセージがネットワークから消えるようにするためです。これにより、次の新しい接続が古い接続要求メッセージを受け取ることがありません。

TCP の信頼性のある伝送#

TCP はタイムアウト再送を使用して信頼性のある伝送を実現します:すでに送信されたメッセージセグメントがタイムアウト時間内に確認を受け取らなかった場合、そのメッセージセグメントを再送信します。

メッセージセグメントが送信されてから確認を受け取るまでにかかる時間を往復時間 RTT と呼び、加重平均往復時間 RTTs は以下のように計算されます:

image

ここで、0 ≤ a < 1 であり、RTTs は a の増加に伴い RTT の影響を受けやすくなります。

タイムアウト時間 RTO は RTTs よりもわずかに大きくする必要があります。TCP で使用されるタイムアウト時間の計算は以下の通りです:

image

ここで RTTd は偏差の加重平均値です。

TCP スライディングウィンドウ#

ウィンドウはバッファの一部であり、バイトストリームを一時的に保存するために使用されます。送信者と受信者はそれぞれウィンドウを持ち、受信者は TCP メッセージセグメント内のウィンドウフィールドを通じて送信者に自分のウィンドウサイズを知らせ、送信者はこの値と他の情報に基づいて自分のウィンドウサイズを設定します。

送信ウィンドウ内のバイトはすべて送信が許可され、受信ウィンドウ内のバイトはすべて受信が許可されます。送信ウィンドウの左側のバイトがすでに送信され、確認を受け取った場合、送信ウィンドウは一定の距離だけ右にスライドします。左側の最初のバイトが送信済みかつ確認済みの状態でない限り、受信ウィンドウのスライドも同様です。受信ウィンドウの左側のバイトがすでに送信され、確認され、ホストに配信されると、受信ウィンドウは右にスライドします。

受信ウィンドウはウィンドウ内の最後の順序で到達したバイトのみを確認します。例えば、受信ウィンドウがすでに受け取ったバイトが {31, 34, 35} の場合、{31} は順序で到達し、{34, 35} はそうではないため、バイト 31 のみを確認します。送信者はバイトの確認を受け取った後、そのバイト以前のすべてのバイトが受信されたことを知ります。

image

TCP フロー制御#

フロー制御は送信者の送信速度を制御し、受信者が受信できるようにするためのものです。

受信者が送信する確認メッセージ内のウィンドウフィールドは、送信者のウィンドウサイズを制御するために使用でき、これにより送信者の送信速度に影響を与えます。ウィンドウフィールドを 0 に設定すると、送信者はデータを送信できません。

TCP 混雑制御#

ネットワークに混雑が発生すると、パケットが失われ、送信者は再送を続けるため、ネットワークの混雑度がさらに高くなります。したがって、混雑が発生した場合、送信者の速度を制御する必要があります。これはフロー制御と非常に似ていますが、出発点が異なります。フロー制御は受信者が受信できるようにするためのものであり、混雑制御はネットワーク全体の混雑度を低下させるためのものです。

image

TCP は主に四つのアルゴリズムを使用して混雑制御を行います:スロースタート、混雑回避、クイック再送、クイック回復。

送信者は混雑ウィンドウ(cwnd)と呼ばれる状態変数を維持する必要があります。混雑ウィンドウと送信者ウィンドウの違いに注意してください:混雑ウィンドウは単なる状態変数であり、実際に送信者がどれだけのデータを送信できるかは送信者ウィンドウによって決まります。

議論を容易にするために、以下の仮定を行います:

  • 受信者には十分な受信バッファがあるため、フロー制御は発生しません;
  • TCP のウィンドウはバイトに基づいていますが、ここではウィンドウのサイズ単位をメッセージセグメントとします。
image

1. スロースタートと混雑回避#

最初の送信はスロースタートを実行し、cwnd = 1 に設定します。送信者は 1 つのメッセージセグメントしか送信できません。確認を受け取った後、cwnd を倍増させるため、その後送信者が送信できるメッセージセグメントの数は:2、4、8 ...

スロースタートでは各ラウンドごとに cwnd が倍増するため、cwnd の増加速度が非常に速くなり、送信者の送信速度が急速に増加し、ネットワークの混雑の可能性が高くなります。スロースタートの閾値 ssthresh を設定し、cwnd >= ssthresh の場合、混雑回避に入り、各ラウンドで cwnd を 1 増加させます。

タイムアウトが発生した場合、ssthresh = cwnd / 2 に設定し、再度スロースタートを実行します。

2. クイック再送とクイック回復#

受信者では、受信したメッセージセグメントごとに最後に受信した順序のメッセージセグメントを確認する必要があります。例えば、M1 と M2 を受信した場合、M4 を受信したときは、M2 に対する確認を送信する必要があります。

送信者では、三つの重複確認を受け取った場合、次のメッセージセグメントが失われたことがわかります。この場合、クイック再送を実行し、次のメッセージセグメントを即座に再送信します。例えば、三つの M2 を受信した場合、M3 が失われたことがわかり、M3 を即座に再送信します。

この場合、個別のメッセージセグメントが失われただけで、ネットワークが混雑しているわけではありません。したがって、クイック回復を実行し、ssthresh = cwnd / 2、cwnd = ssthresh に設定します。この時点で混雑回避に直接入ります。

スロースタートとクイック回復の「スロースタート」と「クイック回復」は、cwnd の設定値を指し、cwnd の増加速度を指すわけではありません。スロースタートでは cwnd を 1 に設定し、クイック回復では cwnd を ssthresh に設定します。

image

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。